/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation
**
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/

#include "callinfo_symbian.h"
#include <QDateTime>
#include <e32std.h>

/*!
 * Symbian static constructor.
 */
CallInfoExPrivate* CallInfoExPrivate::NewL(CallInfoEx *aPublicAPI)
{
    CallInfoExPrivate* self = new (ELeave) CallInfoExPrivate(aPublicAPI);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
}

/*!
 * Symbian second stage constructor.
 */
void CallInfoExPrivate::ConstructL()
{
    iTelephony = CTelephony::NewL();
}

/*!
 * Private constructor - initialise the pointer to the public API class
 * and make this high priority for scheduling.
 */
CallInfoExPrivate::CallInfoExPrivate(CallInfoEx *aPublicAPI)
    : iLineStatusV1Pckg(iCallStatusV1), iCallInfoV1Pckg(iCallInfoV1),
      iRemoteInfoV1Pckg(iRemoteInfoV1),
      iPublicAPI(aPublicAPI), CActive(CActive::EPriorityHigh)
{

    // Active objects like this one must register
    // themselves with an Active scheduler.
    CActiveScheduler::Add(this);
}

CallInfoExPrivate::~CallInfoExPrivate()
{
    // Cancel any outstanding requests before this object is destroyed.
    // This destructor cannot leave - so trap any problems here.

    Cancel(); //  Calls DoCancel()
    delete iTelephony;
}


/*!
 * Public interface slot implementation - start notification.
 */
void CallInfoExPrivate::startNotification()
{
    iTelephony->NotifyChange(iStatus,CTelephony::EVoiceLineStatusChange, iLineStatusV1Pckg );
    SetActive();
}

/*!
 * Get the call information.
 */
void CallInfoExPrivate::GetCallInfo()
{
    CTelephony::TCallSelectionV1 callSelectionV1;
    CTelephony::TCallSelectionV1Pckg callSelectionV1Pckg( callSelectionV1 );
    callSelectionV1.iLine = CTelephony::EVoiceLine;
    callSelectionV1.iSelect = CTelephony::EInProgressCall;

    // Retrieves information about the call selected by the aCallSelect argument.
    iTelephony->GetCallInfo(callSelectionV1Pckg, iCallInfoV1Pckg, iRemoteInfoV1Pckg);

    emit iPublicAPI->updateCallInfo("................\n");
    emit iPublicAPI->updateCallInfo("Time:");
    emit iPublicAPI->updateCallInfo(QTime::currentTime().toString());
    emit iPublicAPI->updateCallInfo("Date:");
    emit iPublicAPI->updateCallInfo(QDate::currentDate().toString());

    QString displayNumber;

    if(iCallInfoV1.iStatus == CTelephony::EStatusRinging){
    displayNumber = QString::fromUtf16(iRemoteInfoV1.iRemoteNumber.iTelNumber.Ptr(),
                                               iRemoteInfoV1.iRemoteNumber.iTelNumber.Length());
    emit iPublicAPI->updateCallInfo("Call Received from :");
    }
    else{
    displayNumber = QString::fromUtf16(iCallInfoV1.iDialledParty.iTelNumber.Ptr(),
                                               iCallInfoV1.iDialledParty.iTelNumber.Length());
    emit iPublicAPI->updateCallInfo("Dialling :");
    }

    emit iPublicAPI->updateCallInfo(displayNumber);
    emit iPublicAPI->updateCallInfo("................\n");
}

/*!
 * Called when an asynchronous service request completes.
 * This is called when the call status changes.
 */
void CallInfoExPrivate::RunL()
{
    CTelephony::TCallStatus voiceLineStatus = iCallStatusV1.iStatus;
    switch(voiceLineStatus)
    {
    case CTelephony::EStatusRinging:
        emit iPublicAPI->updateCallStatus(".......................");
        emit iPublicAPI->updateCallStatus("Phone is ringing");
        GetCallInfo();
        break;

    case CTelephony::EStatusAnswering:
        emit iPublicAPI->updateCallStatus(".......................");
        emit iPublicAPI->updateCallStatus("Answering");
        break;

    case CTelephony::EStatusDisconnecting:
        emit iPublicAPI->updateCallStatus(".......................");
        emit iPublicAPI->updateCallStatus("Disconnecting");
        break;

    case CTelephony::EStatusDialling:
        emit iPublicAPI->updateCallStatus(".......................");
        emit iPublicAPI->updateCallStatus("Dialling");
        GetCallInfo();
        break;

    case CTelephony::EStatusConnecting:  
        emit iPublicAPI->updateCallStatus(".......................");
        emit iPublicAPI->updateCallStatus("Connecting");
        break;

    case CTelephony::EStatusConnected:
        emit iPublicAPI->updateCallStatus(".......................");
        emit iPublicAPI->updateCallStatus("Connected");
        break;

    case CTelephony::EStatusHold:
        emit iPublicAPI->updateCallStatus(".......................");
        emit iPublicAPI->updateCallStatus("Hold");
        break;

    case CTelephony::EStatusIdle:
        emit iPublicAPI->updateCallStatus(".......................");
        emit iPublicAPI->updateCallStatus("Idle");
        break;
    }
    if(!IsActive()){
    iTelephony->NotifyChange(iStatus,CTelephony::EVoiceLineStatusChange, iLineStatusV1Pckg );
    SetActive();
    }
}

/*!
 * Cancel an outstanding asynchronous request.
 * What to do here depends on what state the call is in.
 */
void CallInfoExPrivate::DoCancel()
{
	iTelephony->CancelAsync(CTelephony::EVoiceLineStatusChangeCancel);
}




